package com.financing.wap.web.controller.api;

import java.math.BigDecimal;
import java.util.Date;
import java.util.UUID;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

import com.financing.wap.service.IDstIntegralRuleService;
import org.apache.commons.io.IOUtils;
import org.apache.log4j.Logger;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.ResponseBody;

import com.financing.wap.common.CommonConstantUtil.CommonStatus;
import com.financing.wap.common.ResultMap;
import com.financing.wap.dto.DstUserPayLogDTO;
import com.financing.wap.dto.DstVirtualGoodsDTO;
import com.financing.wap.service.IDstUserPayLogService;
import com.financing.wap.service.IDstVirtualGoodsService;
import com.financing.wap.service.weixin.service.WeixinPayService;
import com.financing.wap.util.DateUtil;
import com.financing.wap.util.IPUtil;
import com.financing.wap.util.StringUtil;
import com.financing.wap.web.controller.BaseController;
import com.github.binarywang.wxpay.bean.notify.WxPayNotifyResponse;
import com.github.binarywang.wxpay.bean.notify.WxPayOrderNotifyResult;
import com.github.binarywang.wxpay.bean.request.BaseWxPayRequest;
import com.github.binarywang.wxpay.bean.request.WxPayUnifiedOrderRequest;
import com.github.binarywang.wxpay.bean.result.BaseWxPayResult;

/**
 * @author Binary Wang
 */
@Controller("wxPayController")
@RequestMapping("/wxapi/pay")
public class WxPayController extends BaseController{

	@Autowired
	WeixinPayService payService;
	
	@Autowired
	IDstUserPayLogService dstUserPayLogService;
	
	@Autowired
	IDstVirtualGoodsService dstVirtualGoodsService;

	@Autowired
	private IDstIntegralRuleService dstIntegralRuleService;

	private Logger logger = Logger.getLogger(getClass());
	
	/***
	 * 统一创建订单
	 * @param request
	 * @param dstUserIntegralFlow
	 * @param pager
	 * @return
	 */
	@RequestMapping("/createOrder")
	@ResponseBody
	public synchronized ResultMap createOrder(HttpServletRequest request){
		ResultMap result = new ResultMap();
		try{
			logger.info(" createOrder  begin .......");
			String openid = request.getParameter("openid");
			
			String productId = request.getParameter("productId");
			if(StringUtil.isNullOrEmptyStr(openid,productId)){
				result.setStatusCode(ResultMap.STATUS_CODE_PARAMETERS_LOSE);
				result.setStatus(ResultMap.STATUS.FAILE);
				return result;
			}
			DstVirtualGoodsDTO goods = dstVirtualGoodsService.loadById(Integer.parseInt(productId));
			if(goods.getId()==null){
				result.setStatusCode(ResultMap.STATUS_CODE_PARAMETERS_LOSE);
				result.setStatus(ResultMap.STATUS.FAILE);
				return result;
			}
			
			BigDecimal amount=goods.getGoodsAmount();
			String orderNo = UUID.randomUUID().toString().replace("-", "");
			
		    DstUserPayLogDTO dstUserPayLog=new DstUserPayLogDTO();
		    dstUserPayLog.setPayUserOpenid(openid);
		    dstUserPayLog.setPayProductId(Integer.parseInt(productId));
		    dstUserPayLog.setPayOrderNo(orderNo);
		    dstUserPayLog.setPayAmount(amount);
		    dstUserPayLog.setPayStatus(CommonStatus.PAY_STATUS_1);
		    dstUserPayLogService.insert(dstUserPayLog);
		    
			WxPayUnifiedOrderRequest orderRequest = new WxPayUnifiedOrderRequest();
		    orderRequest.setBody("购买"+goods.getGoodsName()+"会员");
			orderRequest.setOutTradeNo(orderNo);
		    orderRequest.setTotalFee(BaseWxPayRequest.yuanToFen(amount.toString()));//元转成分
		    orderRequest.setOpenid(openid);
		    orderRequest.setSpbillCreateIp(IPUtil.getRemoteHost(request));
		    orderRequest.setTimeStart(DateUtil.getDate("yyyyMMddHHmmss"));
		    orderRequest.setTimeExpire(DateUtil.getString(DateUtil.addMinute(new Date(),20),"yyyyMMddHHmmss"));
		    Object createOrder = payService.createOrder(orderRequest);
		    //订单是否创建成功
		    logger.info("createOrder result:"+createOrder);
		    
		    result.setAttribute("pay",createOrder);
			result.setStatusCode(ResultMap.STATUS_CODE_SUCCESS);
			result.setStatus(ResultMap.STATUS.SUCCESS);
			
			logger.info("createOrder   end .......");
		}catch(Exception e){
			logger.error("createOrder error!",e);
			result.setStatus(ResultMap.STATUS.ERROR);
			result.setStatusCode(ResultMap.STATUS_CODE_SYS_EXCEPTION);
		}
		return result;
	}
	
	
	/***
	 * 微信支付回调
	 * @param request
	 * @return
	 */
	@RequestMapping("/payNotify")
	@ResponseBody
	public synchronized String payNotify(HttpServletRequest request,HttpServletResponse response){
		logger.info(" payNotify  begin .......");
		try {
		    String xmlResult = IOUtils.toString(request.getInputStream(), request.getCharacterEncoding());
		    WxPayOrderNotifyResult result = payService.parseOrderNotifyResult(xmlResult);
		    String returnCode = result.getReturnCode();
		    String orderId = result.getOutTradeNo();
		    String transactionId = result.getTransactionId();
		    String openid = result.getOpenid();
		    String totalFee = BaseWxPayResult.fenToYuan(result.getTotalFee());
		    String timeEnd = result.getTimeEnd();
		    // 结果正确
		    DstUserPayLogDTO dstUserPayLog=new DstUserPayLogDTO();
		    
		    dstUserPayLog.setPayUserOpenid(openid);
		    DstUserPayLogDTO dto = dstUserPayLogService.queryListGetFirst(dstUserPayLog);
		    if(dto.getId()==null){
		    	logger.info("payNotify result dto is null,orderNo:"+orderId+",openid:"+openid+",totalFee:"+totalFee+",date:"+timeEnd);
		    	 return WxPayNotifyResponse.success("处理成功!");
		    }
		    if("SUCCESS".equals(returnCode)){
		    	// 需要判断订单是否已经支付过，否则可能会重复调用   金额是否一致
		    	if(!"2".equals(dto.getPayStatus())
		    			&&totalFee.equals(dto.getPayAmount().toString())){
		    		dto.setPayDate(new Date());
		    		dto.setPayStatus(CommonStatus.PAY_STATUS_2);
		    		dto.setPayTransactionId(transactionId);
		    		dstUserPayLogService.update(dto);
		    		logger.info("pay scucess ,orderNo:"+orderId+",openid:"+openid+",totalFee:"+totalFee+",date:"+timeEnd);
		    		//支付成功 处理赠送 会员  积分逻辑
		    		// 送积分,给邀请人分红
					dstIntegralRuleService.executePay(openid,dto.getPayProductId(),orderId);
		    	}else{
		    		logger.info("pay scucess but getPayStatus is 2 or totalFee not eq payAmount,orderNo:"+orderId+",openid:"+openid+",totalFee:"+totalFee+",dto.getPayAmount():"+dto.getPayAmount().toString()+",date:"+timeEnd);
		    	}
		    }else {
		    	if(!"2".equals(dto.getPayStatus())){
		    		dto.setPayDate(new Date());
		    		dto.setPayStatus(CommonStatus.PAY_STATUS_3);
		    		dto.setPayTransactionId(transactionId);
		    		dstUserPayLogService.update(dto);
		    	}
		    	logger.info("pay call back fail."+result);
		    }
		    logger.info(" payNotify  end .......");
		    return WxPayNotifyResponse.success("处理成功!");
		  } catch (Exception e) {
		    log.error("微信回调结果异常,异常原因{}", e);
		    return WxPayNotifyResponse.fail(e.getMessage());
		  }
	}
}
